/*
This file contains:
	ALL "GUI" globals, but not "normal" globals used in the actual code, just Gtk vars
	Initializer methods
*/

#ifndef	_GUI_GLOBALS_H_
#define _GUI_GLOBALS_H_

//============================================
//	GTK+ libraries.
//============================================
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <fstream>
#include <stdio.h>

GtkBuilder *builder;
//Windows 
GtkWidget *window;
GtkWidget *aboutWindow;
GtkWidget *helpWindow;
GtkWidget *deviceSelecter;
GtkWidget *promWindow;
GtkWidget *startSession;
GtkWidget *openSession;
GtkWidget *nameNewSession;
//Other things...
GtkListStore *paxList;
GtkTreeIter paxListItr;
GtkWidget *paxListView;
GtkWidget *paxListViewScroll;
GtkTreeSelection *listPacket;
GtkWidget *paxDat;
GtkListStore *deviceList;
GtkTreeIter deviceListItr;
GtkWidget *deviceListView;
GtkTreeSelection *listDevice;
GtkWidget *bitView;
//Text Buffers
GtkTextBuffer *paxDatText;
GtkTextBuffer *bitViewText;
//Buttons
GtkWidget *closeHelpButton;
GtkWidget *selectDeviceButton;
GtkWidget *promOn, *promOff;
GtkWidget *startNew, *resumePrevious;
//Menu items
GtkWidget *openSess, *saveSess, *quit;
GtkWidget *startCapture, *stopCapture, *selectCapture, *promToggle;
GtkWidget *help, *about;

//Functional prototypes
void deviceSelected();
void packetSelected();
void quitProgram();
void closeHelp();
void closeAbout();
void setPromOn();
void setPromOff();
void startNewSession();
void resumePreviousSession(GtkWidget* sender);
void saveSession();
void startSniffing();
void stopSniffing();
void selectSource();
void getHelp();
void findOutAbout();
void togglePromiscuity();
void fillDeviceList();

//Initializes numerous signals for all sorts of different widgets and dealies and such
void initSignals() {
	//For when the device select button is pressed
	g_signal_connect(G_OBJECT(selectDeviceButton), "clicked", G_CALLBACK(deviceSelected), NULL);
	g_signal_connect(deviceListView, "row-activated", G_CALLBACK(deviceSelected), NULL);
	//For when the selected item in the packet list is changed
	g_signal_connect(listPacket, "changed", G_CALLBACK(packetSelected), NULL);
	//For when the "X" to close the program is clicked
	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(quitProgram), NULL);
	//For when the "X" to close the device selector is pressed
	g_signal_connect(G_OBJECT(deviceSelecter), "destroy", G_CALLBACK(quitProgram), NULL);
	//For when the "X" to close the start session is pressed
	g_signal_connect(G_OBJECT(startSession), "destroy", G_CALLBACK(quitProgram), NULL);
	//For when the "X" to close the open session is pressed
	g_signal_connect(G_OBJECT(openSession), "destroy", G_CALLBACK(quitProgram), NULL);
	//For when the "X" to close the create session is pressed
	g_signal_connect(G_OBJECT(nameNewSession), "destroy", G_CALLBACK(quitProgram), NULL);
	//For when the "Close" button is pressed in Help
	g_signal_connect(G_OBJECT(closeHelpButton), "clicked", G_CALLBACK(closeHelp), NULL);
	//For when the "On" button is pressed in Promiscuous
	g_signal_connect(G_OBJECT(promOn), "clicked", G_CALLBACK(setPromOn), NULL);
	//For when the "On" button is pressed in Promiscuous
	g_signal_connect(G_OBJECT(promOff), "clicked", G_CALLBACK(setPromOff), NULL);
	//For when the "Start New" button is pressed in Session Select
	g_signal_connect(G_OBJECT(startNew), "clicked", G_CALLBACK(startNewSession), NULL);
	//For when the "Resume Previous" button is pressed in Session Select
	g_signal_connect(G_OBJECT(resumePrevious), "clicked", G_CALLBACK(resumePreviousSession), &resumePrevious);

	//Menu items
	//File->Open
	g_signal_connect(G_OBJECT(openSess), "activate", G_CALLBACK(resumePreviousSession), &openSess);
	//File->Save
	g_signal_connect(G_OBJECT(saveSess), "activate", G_CALLBACK(saveSession), NULL);
	//File->Quit
	g_signal_connect(G_OBJECT(quit), "activate", G_CALLBACK(quitProgram), NULL);
	//Action->Start Capture
	g_signal_connect(G_OBJECT(startCapture), "activate", G_CALLBACK(startSniffing), NULL);
	//Action->Stop Capture
	g_signal_connect(G_OBJECT(stopCapture), "activate", G_CALLBACK(stopSniffing), NULL);	
	//Action->Select Source
	g_signal_connect(G_OBJECT(selectCapture), "activate", G_CALLBACK(selectSource), NULL);
	//Action->Promiscuous Toggle
	g_signal_connect(G_OBJECT(promToggle), "activate", G_CALLBACK(togglePromiscuity), NULL);	
	//Help->Help
	g_signal_connect(G_OBJECT(help), "activate", G_CALLBACK(getHelp), NULL);
	//Help->About
	g_signal_connect(G_OBJECT(about), "activate", G_CALLBACK(findOutAbout), NULL);

	gtk_builder_connect_signals (builder, NULL);
}

void buildListViews() {
	GtkCellRenderer *renderer;

	//FOR PAXLIST
	//Column 1
	renderer = gtk_cell_renderer_text_new ();
  	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(paxListView), -1, "ID", renderer, "text", 0, NULL);
  	//Column 2
  	renderer = gtk_cell_renderer_text_new ();
  	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(paxListView), -1, "ORIGIN", renderer, "text", 1, NULL);
	//Column 3
	renderer = gtk_cell_renderer_text_new ();
  	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(paxListView), -1, "DESTINATION", renderer, "text", 2, NULL);
  	//Column 4
  	renderer = gtk_cell_renderer_text_new ();
  	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(paxListView), -1, "PROTOCOL", renderer, "text", 3, NULL);
	
	//FOR DEVICELIST
	//Column 1 (the only column)
	renderer = gtk_cell_renderer_text_new ();
  	gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(deviceListView), -1, "SELCET A DEVICE TO LISTEN TO", renderer, "text", 0, NULL);
}

void initButtons() {
	closeHelpButton = GTK_WIDGET(gtk_builder_get_object(builder, "closeHelp"));
	selectDeviceButton = GTK_WIDGET(gtk_builder_get_object(builder, "select"));
	promOn = GTK_WIDGET(gtk_builder_get_object(builder, "promOn"));
	promOff = GTK_WIDGET(gtk_builder_get_object(builder, "promOff"));
	startNew = GTK_WIDGET(gtk_builder_get_object(builder, "startNew"));
	resumePrevious = GTK_WIDGET(gtk_builder_get_object(builder, "resumePrevious"));
}

void initWindows() {
	window = GTK_WIDGET (gtk_builder_get_object(builder, "window"));
	aboutWindow = GTK_WIDGET(gtk_builder_get_object(builder, "aboutWindow"));
	helpWindow = GTK_WIDGET(gtk_builder_get_object(builder, "helpWindow"));
	deviceSelecter = GTK_WIDGET(gtk_builder_get_object(builder, "deviceSelecter"));
	promWindow = GTK_WIDGET(gtk_builder_get_object(builder, "promWindow"));
	startSession = GTK_WIDGET(gtk_builder_get_object(builder, "startSession"));
	openSession = gtk_file_chooser_dialog_new("Open Session",GTK_WINDOW(window),
		GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,
		GTK_RESPONSE_ACCEPT, NULL);
	nameNewSession = gtk_file_chooser_dialog_new("Create Session",GTK_WINDOW(window),
		GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, "C_reate",
		GTK_RESPONSE_ACCEPT, NULL);
}

void initMenuItems() {
	openSess = GTK_WIDGET(gtk_builder_get_object(builder, "open"));
	saveSess = GTK_WIDGET(gtk_builder_get_object(builder, "save"));
	quit = GTK_WIDGET(gtk_builder_get_object(builder, "quit"));
	startCapture = GTK_WIDGET(gtk_builder_get_object(builder, "startCapture"));
	stopCapture = GTK_WIDGET(gtk_builder_get_object(builder, "stopCapture"));
	selectCapture = GTK_WIDGET(gtk_builder_get_object(builder, "selectCapture"));	
	help = GTK_WIDGET(gtk_builder_get_object(builder, "help"));
	about = GTK_WIDGET(gtk_builder_get_object(builder, "about"));
	promToggle = GTK_WIDGET(gtk_builder_get_object(builder, "promToggle"));
}

void initTextAndViews() {
	//Prepare paxDat stuff
	paxDat = GTK_WIDGET(gtk_builder_get_object(builder, "paxDatView"));
	paxDatText = gtk_text_buffer_new(NULL);
	bitView = GTK_WIDGET(gtk_builder_get_object(builder, "bitView"));
	bitViewText = gtk_text_buffer_new(NULL);
}

void initTreesAndViews() {
	//Prepare packet list
	paxListView = GTK_WIDGET(gtk_builder_get_object(builder, "paxListView"));
	paxListViewScroll = GTK_WIDGET(gtk_builder_get_object(builder, "paxListViewScroll"));
	//Get the selected packet stuff initialized
	//Ties an event to the method to be called when the user changes the packet selected
	listPacket = gtk_tree_view_get_selection(GTK_TREE_VIEW(paxListView));		
	
	//Prepare device list
	deviceListView = GTK_WIDGET(gtk_builder_get_object(builder, "deviceListView"));
	//Get the selected packet stuff initialized
	//Ties an event to the method to be called when the user changes the packet selected
	listDevice = gtk_tree_view_get_selection(GTK_TREE_VIEW(deviceListView));

	buildListViews();

	//Make a new tree store named paxList
	paxList = gtk_list_store_new(4, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);	
	//Tie the tree store and view together
	gtk_tree_view_set_model(GTK_TREE_VIEW(paxListView), GTK_TREE_MODEL(paxList));
	//Make a new tree store named paxList
	deviceList = gtk_list_store_new(1, G_TYPE_STRING);	
	//Tie the tree store and view together
	gtk_tree_view_set_model(GTK_TREE_VIEW(deviceListView), GTK_TREE_MODEL(deviceList));

}

void initializeEverything() {
	//Set builder
	builder = gtk_builder_new ();

	//Quick file check
	//----------------
	ifstream file;
	file.open("sniffer.xml");
	if (!file.is_open())
	{
		cout << "Could not find XML configuration file. Quitting." << endl;
		exit(0);
	}
	file.close();

	//Check if threads are supported
	//TODO: Add error message here!
	//------------------------------
	if (!g_thread_supported())
	{
		g_thread_init(NULL);
		gdk_threads_init();
		dcout("initializeEverything","Thread support initialized.");
	}
	else
	{
		dcout("initializeEverything","g_threads are not supported.");
		exit(0);
	}

	gtk_builder_add_from_file (builder, "sniffer.xml", NULL);
	//Set windows
	initWindows();	
	//Set menu items
	initMenuItems();
	//Buttons
	initButtons();
	//Tex and Views
	initTextAndViews();
	//Trees and Views
	initTreesAndViews();	
	//Initialize all signal connections
	initSignals();
	//Fills the device list
	fillDeviceList();
	g_object_unref(G_OBJECT(builder));
}

#endif	/*	_GUI_GLOBALS_H_		*/
